<template>
  <div>
    <!-- 缩略状态 -->
    <transition name="slide-fade">
      <div
        v-show="!showChatPanel"
        class="fixed right-[0] top-[60%] -translate-y-1/2 flex flex-col justify-center gap-2 items-end"
      >
        <Robot
          :chatAskBox="chatAskBox"
          @show-panel="showChatPanel = true"
          :showChatPanel="showChatPanel"
        ></Robot>
      </div>
    </transition>

    <!-- 聊天面板状态 -->
    <transition name="slide-fade">
      <div
        class="pt-3 px-[20px] pb-2 h-full w-[394px] fixed z-20 right-0 top-0 border-l border-r border-transparent border-base-card bg-chat-panel black:bg-chat-panel-dark"
        v-show="showChatPanel"
        @mouseover="showCloseIcon = true"
        @mouseout="showCloseIcon = false"
      >
        <!-- 关闭/隐藏面板 -->
        <el-icon
          @click="showChatPanel = false"
          v-show="showCloseIcon"
          class="absolute top-1/2 -left-[16px] cursor-pointer h-7 text-text-03 black:text-text-03-dark hover:text-text-01 black:hover:text-text-01-dark"
        >
          <ClosePanel class="!h-7" />
        </el-icon>

        <!-- 内容区 -->
        <div class="h-full flex flex-col rounded-lg bg-transparent pt-4 pb-3 relative">
          <!-- 消息会话区 -->
          <div
            class="flex-grow overflow-y-auto chat-content pb-10"
            v-if="panelMessages.length && initChatMessage"
          >
            <div v-for="(item, index) in panelMessages" :key="index">
              <!-- 历史消息中分割线 -->
              <div v-if="item.first" class="flex justify-center items-center gap-2 mb-4">
                <div class="w-[80px] h-[1px] bg-border-01 black:bg-border-01-dark"></div>
                <div class="text-xs text-text-03 black:text-text-03-dark">全新的会话</div>
                <div class="w-[80px] h-[1px] bg-border-01 black:bg-border-01-dark"></div>
              </div>
              <!-- 消息列表 -->
              <ChatMessage
                :msg-id="item.id"
                :chatMessages="item"
                :latest="index === panelMessages.length - 1"
                @islike="islike(item)"
              />
              <!-- 未生成过结果时点击清除上下文分割线 -->
              <div
                v-if="
                  index === panelMessages.length - 1 && item.group_session_id !== groupSessionId
                "
                ref="clearContextLine"
                class="flex justify-center items-center gap-2 mb-4"
              >
                <div class="w-[80px] h-[1px] bg-border-01 black:bg-border-01-dark"></div>
                <div class="text-xs text-text-03 black:text-text-03-dark">全新的会话</div>
                <div class="w-[80px] h-[1px] bg-border-01 black:bg-border-01-dark"></div>
              </div>
            </div>
          </div>
          <div
            v-if="!panelMessages.length"
            class="flex-grow flex flex-col gap-2 justify-center items-center"
          >
            <div>
              <el-icon class="!w-[48px] !h-[48px]"
                ><AIMESimple class="!w-[48px] !h-[48px]"
              /></el-icon>
            </div>
            <div class="text-2xl font-semibold">您好！我是Aime</div>
            <div class="text-text-03 black:text-text-03-dark text-sm text-center">
              我可以帮你生成基本面分析，查找个股数据，<br />并生成可视化图表
            </div>
          </div>

          <!-- 输入框、推荐问句区 -->
          <ChatAskBox ref="chatAskBox" :loading="messageLoading" />

          <!-- 未登录状态 -->
          <div
            class="w-full h-full absolute bg-background-01 black:bg-background-01-dark bg-opacity-80 flex flex-col justify-center items-center left-0 top-0 gap-1"
            v-if="!loginStatusInJS"
          >
            <el-icon class="w-6 h-6">
              <Lock class="!w-6 !h-6" />
            </el-icon>
            <span class="text-text-01 black:text-text-01-dark font-semibold">
              <span class="text-text-04 black:text-text-04-dark cursor-pointer" @click="login"
                >登录</span
              >
              解锁对话功能
            </span>
          </div>
        </div>

        <!-- 点踩反馈面板 -->
        <el-drawer
          v-model="drawer"
          :with-header="false"
          direction="btt"
          class="rounded-t-lg !h-[330px]"
        >
          <ChatFeedback @close="drawer = false" :message="feedbackMessage" />
        </el-drawer>
      </div>
    </transition>
  </div>
</template>
<script setup lang="ts">
import { AIMESimple, Lock, ClosePanel } from '@/components/icons'
import ChatAskBox from './chat/ChatAskBox.vue'
import ChatMessage from './chat/ChatMessage.vue'
import ChatFeedback from './chat/ChatFeedback.vue'
import Robot from './Robot.vue'
import { computed, getCurrentInstance, nextTick, ref, watch, type Ref } from 'vue'
import { useSessionStore } from '@/stores/session'
import { getChatHistory, resetChat } from '../services/chat-api'
import type { ChatMessages } from '@/common/models/chat-message'
import { useChatMessage } from '../services/chat-message-handler'
import { getEventBus } from '@/common/services/chat-event-bus'
import { useAppInfoStore } from '@/stores/app'
import { ERRORTYPE } from '@/common/config/const'

const { proxy } = getCurrentInstance()!

const emits = defineEmits(['showChatPanel'])

// 显示聊天面板
const showChatPanel = ref(false)

// 显示面板收起按钮
const showCloseIcon = ref(false)

const { messageEventBus, messageRegenerateEventBus, chatResetEventBus } = getEventBus()

// 消息列表
const panelMessages: Ref<ChatMessages[]> = ref([])

// 输入框dom元素
const chatAskBox = ref()

// 消息加载状态
const messageLoading = ref(false)

const drawer = ref(false)

const feedbackMessage: Ref<ChatMessages | null> = ref(null)

const loginStatusInJS = computed(() => window.loginIssue.isLogin())

const groupSessionId = computed(() => useSessionStore().session?.group_session_id)

const initChatMessage = ref(false)

const appStore = useAppInfoStore()

const skin = computed(() => appStore.skin)

const messageGroup: Ref<Map<string, ChatMessages[]>> = ref(new Map())

const isClient = computed(() => appStore.isClient())

// 取数：历史消息 并设置session
async function getHistoryMessage() {
  const res = await getChatHistory()
  useSessionStore().setSession(res.session)
  panelMessages.value = res.messages
  setMessageGroup()
}

function setMessageGroup() {
  panelMessages.value.forEach((item) => {
    const group = messageGroup.value.get(item.group_session_id!)
    if (group) {
      group.push(item)
    } else {
      item.first = true
      messageGroup.value.set(item.group_session_id!, [item])
    }
  })
}

getHistoryMessage()

// 监听：用户问句消息发送
messageEventBus.on(async (askMessage) => {
  let group = messageGroup.value.get(groupSessionId.value!)
  askMessage.group_session_id = groupSessionId.value!
  if (group) {
    group.push(askMessage)
  } else {
    group = [askMessage]
    askMessage.first = true
    messageGroup.value.set(groupSessionId.value!, group)
  }
  messageLoading.value = true
  panelMessages.value.push(askMessage)
  // 通过流式接口处理消息
  await nextTick()
  const { message, request } = useChatMessage(askMessage)
  console.log('add message')
  message.group_session_id = groupSessionId.value!
  panelMessages.value.push(message)
  group.push(message)
  // 重置输入框状态
  await nextTick()
  chatAskBox.value.resetAskBoxStatus()
  chatAskBox.value.resetQuestion()
  await request
  messageLoading.value = false
})

// 监听：重新生成消息
messageRegenerateEventBus.on(async () => {
  messageLoading.value = true
  panelMessages.value.pop()
  panelMessages.value = Array.from(panelMessages.value)
  await nextTick()
  const { message, request } = useChatMessage(panelMessages.value[panelMessages.value.length - 1])
  // 重新生成消息
  const group = messageGroup.value.get(groupSessionId.value!)
  group?.pop()
  message.group_session_id = groupSessionId.value!
  group?.push(message)

  panelMessages.value.push(message)
  await request
  messageLoading.value = false
})

// 监听：重置聊天面板
chatResetEventBus.on(async () => {
  try {
    const res = await resetChat()
    useSessionStore().setSession(res)
    await nextTick()
    const clearContextLine = proxy?.$refs.clearContextLine as HTMLElement[]
    if (clearContextLine && clearContextLine.length > 0) {
      clearContextLine[0].scrollIntoView({
        behavior: 'smooth',
        block: 'start',
        inline: 'center'
      })
    }
  } catch (error) {
    window.f10log(ERRORTYPE.AJAX, `清除上下文失败：${error}`, error)
  }
})

function islike(message: ChatMessages) {
  feedbackMessage.value = message
  drawer.value = true
}

function login() {
  const win: any = window
  if (isClient.value) {
    win.API.use({
      method: 'Util.reStartHx',
      success: function (data: any) {
        console.log(data)
      }
    })
  } else {
    window.location.href = `https://upass.10jqka.com.cn/login?redir=${location.href}`
  }
}

watch(skin, () => {
  if (!showChatPanel.value) {
    initChatMessage.value = false
  }
})

watch(showChatPanel, (newVal) => {
  emits('showChatPanel', newVal)
  if (newVal) {
    initChatMessage.value = true
  }
})
</script>
